package org.grottarossa.ui.core.casemanagement.bpm;

import java.util.ArrayList;
import java.util.Observable;

import org.grottarossa.template.data.pojo.workflows.Activity;
import org.grottarossa.template.data.pojo.workflows.Dispatch;
import org.grottarossa.template.data.pojo.workflows.WorkItem;
import org.grottarossa.template.data.pojo.workflows.Workflow;
import org.grottarossa.template.drivers.DriverException;
import org.grottarossa.template.drivers.components.tokens.WorkFlowId;
import org.grottarossa.ui.core.ApplicationSession;
import org.grottarossa.ui.core.base.BasePanel;
import org.grottarossa.ui.core.casemanagement.menu.ServicesMenuPanel;


import com.vaadin.ui.Panel;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;

/**
*
* La Classe rappresenta il Dispatch Listener che si occupa di gestire gli eventi sui dispatch buttons.
*
* @author Marco Sabatini (sabatini.m@gmail.com)
* @author Maurizio Farina (maurizio.farina@gmail.com)
* @author Marco Trischitta ()
* @version %I%, %G%
* @since 1.0
*
* */
public class BPMDispatchListener extends Observable implements ClickListener
{
	private static final long serialVersionUID = -4296685511359672837L;
	/**Rappresenta l'istanza di un processo.*/
	private WorkItem workItem;
	/**Rappresenta l'oggetto dispatch.*/

	private Workflow workFlow;

	private Dispatch dispatch;
	/**Rappresenta il panel a cui viene associato il BPMDispatchListener.
	 * Il panel verr� modificato in funzione degli eventi associati al listener.
	 * */
	private BasePanel panel;
	private ArrayList<IAction> m_onCloseActions;
	private final ApplicationSession m_appSession;

	/**Costruttore vuoto.*/
	public BPMDispatchListener(ApplicationSession appSession){
		this.m_appSession = appSession;}

	/**
	 * Costruttore dell'oggetto.
	 *
	 * @param workItem E' l'istanza di processo.
	 * @param dispatch E' l'oggetto dispatch con le informazioni riguardanti i dispatch button definiti nell'attivita' di processo.
	 * @param panel E' il panel associato al listener che viene modificato in funzione dell'action definita in quest'ultimo
	 * @param onCloseActions
	 *
	 * */
	public BPMDispatchListener(ApplicationSession appSession, WorkItem workItem, Dispatch dispatch, BasePanel panel, ArrayList<IAction> onCloseActions)
	{
		m_appSession = appSession;
		this.workItem = workItem;
		this.dispatch = dispatch;
		this.panel = panel;
		m_onCloseActions = onCloseActions;
	}

	/**
	 * Il metodo viene implementato in funzione dell'evento di click sul pulsante di dispatch.
	 * Questo effettua il dispatch su una specifica attivita' del processo, permettendo a quest'ultimo
	 * di proseguire nel suo flusso.
	 *
	 * */
	public void buttonClick(ClickEvent event)
	{
		try
		{
			m_appSession.getBuilder().getWorkflowManagement().routeEnvelope(workItem, dispatch);

			if(dispatch.isImmediate())
			{
				//wizard
				try
				{
					if ( workItem.isLockedBy( m_appSession.getBuilder().getIdentity().getUser() ) /*&& !activity.getActivityName().equals("Stop")*/ )
					{
						Workflow wf = new Workflow(new WorkFlowId( workItem.getWorkflowId() ), workItem.getWorkflowVersion());
						Activity activity =  m_appSession.getBuilder().getWorkflowManagement().getActivity(wf, workItem.getActivityName());
						WorkItem newWorkItem  = m_appSession.getBuilder().getWorkflowManagement().getWorkItem(wf, activity,workItem);


						Activity newActivity = m_appSession.getBuilder().getWorkflowManagement().getActivity(wf, newWorkItem);
						BaseBPMPanel panel2 = (BaseBPMPanel) panel;
						panel2.reload(newWorkItem, newActivity, wf);
					}
					else
						onTerminate();
				}
				catch (Exception e)
				{
					panel.removeAllComponents();
					panel.showError(e);
				}
			}
			else
				onTerminate();
		}
		catch (DriverException e)
		{
			setChanged();
			panel.showError(e);
		}
	}

	private void onTerminate()
	{
		panel.removeAllComponents();

		if(m_onCloseActions != null)
			for(IAction action : m_onCloseActions)
			{
				action.execute();
			}
	}
}